from skimage import io, transform
from code.flaw import Flaw
from code.sample import Sample

# 有效瑕疵占比
EFFECT_PERCENT = 0.05


def get_small_samples(url):
    """
    传入图片链接，将图片剪裁旋转等处理，获取一批小图片。且保证前8张是大图直接缩放，有较大视野

    返回值Sample列表

    图片数量：共 (2 + 12 * 9) * 4 = 440
    大图剪裁两份直接缩放 2、
    剪裁 12 * 9
    所有图片4方向翻转  * 4

    :param url: 图片链接，图片大小2560*1920
    :return: small_samples Sample列表 小图大小224*224
    """
    small_samples = []  # 所有小图片

    img = io.imread(url)
    flaw = Flaw(url)

    # 直接切两半缩放
    # 左半部分 pos(xmin,ymin,xmax,ymax)
    pos = (0, 0, 1920, 1920)
    temp_imag = transform.resize(img[pos[1]:pos[3], pos[0]:pos[2], :],
                                 (224, 224), anti_aliasing=True,
                                 preserve_range=True,
                                 mode='constant').astype('uint8')
    # 瑕疵占比 只有当占比达到EFFECT_PERCENT以上才认为该小图有瑕疵
    percent = __flaw_percent_of_small_pic(flaw.poses, pos)
    temp_flaw_id = flaw.id if percent > EFFECT_PERCENT else 0
    small_samples.append(Sample(image=temp_imag, flaw_id=temp_flaw_id))

    # 追加各种翻转图
    __append_transpose(small_samples, temp_imag, temp_flaw_id)

    # 右半部分
    pos = (640, 0, 2560, 1920)
    temp_imag = transform.resize(img[pos[1]:pos[3], pos[0]:pos[2], :],
                                 (224, 224), anti_aliasing=True,
                                 preserve_range=True,
                                 mode='constant').astype('uint8')
    # 瑕疵占比 只有当占比达到EFFECT_PERCENT以上才认为该小图有瑕疵
    percent = __flaw_percent_of_small_pic(flaw.poses, pos)
    temp_flaw_id = flaw.id if percent > EFFECT_PERCENT else 0
    small_samples.append(Sample(image=temp_imag, flaw_id=temp_flaw_id))
    # 追加各种翻转图
    __append_transpose(small_samples, temp_imag, temp_flaw_id)

    # 大图剪裁
    for i in range(0, 2337, 212):
        # 为横向最后一张图片特殊处理
        if i == 2332:
            i = 2336
        for j in range(0, 1697, 212):
            pos = (i, j, i + 224, j + 224)
            temp_imag = img[pos[1]:pos[3], pos[0]:pos[2], :]
            # 瑕疵占比 只有当占比达到EFFECT_PERCENT以上才认为该小图有瑕疵
            percent = __flaw_percent_of_small_pic(flaw.poses, pos)
            temp_flaw_id = flaw.id if percent > EFFECT_PERCENT else 0
            small_samples.append(Sample(image=temp_imag, flaw_id=temp_flaw_id))

            # 追加各种翻转图
            __append_transpose(small_samples, temp_imag, temp_flaw_id)

    return small_samples


def __append_transpose(small_samples, image, flaw_id):
    """
    往small_pics列表中追加image的各种翻转图
    :param small_samples: 待追加的列表
    :param image: 待翻转的图片
    :param flaw_id: 瑕疵编号
    :return:None
    """
    # 左右翻转
    small_samples.append(Sample(image=image[:, ::-1], flaw_id=flaw_id))
    # 上下翻转
    small_samples.append(Sample(image=image[::-1], flaw_id=flaw_id))
    # 上下翻转+左右翻转
    small_samples.append(Sample(image=image[::-1, ::-1], flaw_id=flaw_id))


def __flaw_percent_of_small_pic(flaw_pos_list, pic_pos):
    """
    计算pic中，瑕疵的占比
    :param flaw_pos_list: 字典数组 [{xmin: ,ymin: ,xmax: ,ymax: },{xmin: ,ymin: ,xmax: ,ymax: }...]
    :param pic_pos: 元组 (xmin,ymin,xmax,ymax)
    :return: float型0-1之间 瑕疵的占比
    """
    small_pic_size = (pic_pos[3] - pic_pos[1]) * (
            pic_pos[2] - pic_pos[0])
    # 记录最大占比
    percent = 0
    if flaw_pos_list:  # 如果为None,就没有瑕疵，就返回0
        for flaw_pos in flaw_pos_list:
            xmax = min(flaw_pos['xmax'], pic_pos[2])
            xmin = max(flaw_pos['xmin'], pic_pos[0])
            ymax = min(flaw_pos['ymax'], pic_pos[3])
            ymin = max(flaw_pos['ymin'], pic_pos[1])
            width = xmax - xmin
            height = ymax - ymin
            if width < 0 or height < 0: continue
            area = width * height
            # 记录此次占比
            this_percent = area / small_pic_size
            if this_percent > percent: percent = this_percent
    return percent
